#pragma once

#include <cassert>
#include <cerrno>
#include <cstddef>
#include <cstdlib>
#include <exception>
#include <limits>
#include <memory>
#include <stdexcept>
#include <type_traits>
#include <utility>
#include <iostream>

namespace good_cptl
{
template <typename T>
class SysAllocator
{
private:
  using Self = SysAllocator<T>;
public:
  using value_type = T;
  constexpr SysAllocator() = default;
  constexpr SysAllocator(const Self&) noexcept = default;
  T* allocate(size_t count)
  {
    auto const p = std::malloc(sizeof(T) * count);
    if (!p) {
      throw std::bad_alloc();
    }
    return static_cast<T*>(p);
  }
  void deallocate(T* p) {
    if (p == nullptr) return;
    std::free(p);
    p = nullptr;
  }
  void deallocate(T* p, const size_t size) {
    std::cout << "deallocate" << std::endl;
    std::free(p);
    p = nullptr;
  }
};

}